package com.zmzncs.lmtc.common.util;

import com.alibaba.fastjson.JSONObject;
import com.zmzncs.lmtc.common.pojo.chinaums.AgentPayRes;
import com.zmzncs.lmtc.common.pojo.chinaums.PlaceOrderRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
public class ChinaumsUtil {

    final String APPID = "10037e6f6a4e6da4016a66ed122d0011";
    final String APPKEY = "d7ed6a5cc25146b392cfb7b71cabf911";

    public static void main(String args[]) {
        System.out.println(getWriteOffCode());
        System.out.println(getWriteOffCode().length());
//		String token = aMain.getAccessToken();
//		log.info(token);

//		JSONObject s = aMain.placeOrder();
//		System.out.println(s);
    }

    /**
     * 下单
     */
    public static PlaceOrderRes placeOrder(String subOpenId, String orderCode, String totalAmount, String attach){
        JSONObject params = new JSONObject(true);
        params.put("requestTimestamp", DateTimeUtil.getTime());
        params.put("mid", "898201612345678");
        params.put("tid", 88880001);
        params.put("merOrderId", orderCode);
//        params.put("platformAmount", 1);    //  平台商户分 账金额，若分账标记传，则分 账金额必传
        params.put("totalAmount", totalAmount);   //  支付总金额
        params.put("subOpenId", subOpenId); //  用户子标识
        params.put("notifyUrl", "notifyUrl");   //  支付结果通 知地址
        params.put("attachedData", attach);   //  商户附加数据，长度255

//		params.put("tradeType", "MINI");
//		params.put("subAppId", "wx3069280b94304887");
//		params.put("subOpenId", "oquxV4x6hbvjC1szN31yiWtVjbUc");

//		String paramsSha = DigestUtils.sha256Hex(params.toJSONString().getBytes());
//		log.info("" + paramsSha);
//		String str =  APPID + timestamp + nonce + DigestUtils.sha256Hex(params.toJSONString().getBytes());
//		String signature = Base64.getEncoder().encodeToString(HmacUtils.hmacSha256(APPKEY.getBytes(), str.getBytes()));

        Map<String, String> headerMap = new HashMap();
        headerMap.put("Authorization", "OPEN-ACCESS-TOKEN AccessToken=74838104fb514f35866a776d3c1297dc");
//		headerMap.put("Authorization", "OPEN-BODY-SIG AppId=" + APPID + ", Timestamp=" + timestamp + ", Nonce=" + nonce + ", Signature=" + signature);

//        String response = HttpUtil.getIntance().postJson("http://58.247.0.18:29015/v1/netpay/wx/unified-order", params.toJSONString(), headerMap);
//        PlaceOrderRes placeOrderRes = JSONObject.parseObject(response, PlaceOrderRes.class);

        PlaceOrderRes placeOrderRes = new PlaceOrderRes();
        placeOrderRes.setErrCode("SUCCESS");
        return placeOrderRes;
    }

    /**
     * 代付
     */
    public static AgentPayRes agentPay(){
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis());
        String nonce = String.valueOf((int)(1+Math.random()*10000));

        JSONObject params = new JSONObject(true);
        params.put("merNo", "898201612345678");	//	商户号

        JSONObject paramsData = new JSONObject(true);
        paramsData.put("tranId", nonce);	//	交易流水号
        paramsData.put("tranTime", timestamp);			//	交易时间（yyyyMMddHHmmss）
        paramsData.put("currency", "CNY");	//	交易币种（CNY）
        paramsData.put("rcvAcctNo", 1);			//	收款账户号
        paramsData.put("rcvAcctName", 1);	//	收款账户名
        paramsData.put("rcvBankSettleNo", 1);			//	收款行清算联行号（对公必填）
        paramsData.put("tranAmt", 1);	//	交易金额（分）
        paramsData.put("remark", "代付");				//	摘要
        paramsData.put("amtType", 04);		//	资金性质（04：特定商户结算，00：一般性付款）
        paramsData.put("sndAcctNo", 1);			//	付款方账号
        paramsData.put("sndAcctName", 1);		//	付款方户名
        paramsData.put("realMerNo", 1);			//	实际付款商户号
        params.put("data", paramsData);	//	交易请求数据

        Map<String, String> headerMap = new HashMap();
        headerMap.put("Authorization", "OPEN-ACCESS-TOKEN AccessToken=0629356d1b464d68936dee4ef5d91f2a");
        String response = HttpUtil.getIntance().postJson("http://58.247.0.18:29015/v1/itp/tran/pragency/agent-pay", params.toJSONString(), headerMap);
        log.info(response);

        AgentPayRes agentPayRes = JSONObject.parseObject(response, AgentPayRes.class);

        return agentPayRes;
    }

    /**
     * 	获取accessToken
     */
    public String getAccessToken() {
        /*String Timestamp =timestamp;*/
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis());
        String nonce= String.valueOf((int)(1+Math.random()*10000));
        String signature = DigestUtils.sha1Hex(APPID + timestamp + nonce + APPKEY);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", APPID);
        jsonObject.put("timestamp", timestamp);
        jsonObject.put("nonce", nonce);
        jsonObject.put("signature", signature);

        String response = HttpUtil.getIntance().postJson("http://58.247.0.18:29015/v1/token/access", jsonObject.toJSONString());
        log.info(response);

        String accessToken = JSONObject.parseObject(response).get("accessToken").toString();
        return accessToken;
    }

    /**
     * 获取到订单号
     *
     * @param msgSrcId 消息来源编号  1017
     * @return 商户订单号    {来源编号(4位)}{时间(yyyyMMddmmHHssSSS)(17位)}{3位随机数}
     */
    public static String getMerOrderId(String msgSrcId) {
//        return msgSrcId + DateTimeUtil.getMsec() + (int)((Math.random()*9+1)*1000000);
        return msgSrcId + DateTimeUtil.getMsec() + (int)((Math.random()*9+1)*1000);
    }


    /**
     * 获取核销码
     *
     * @return 商户订单号    {来源编号(4位)}{时间(yyyyMMddmmHHssSSS)(17位)}{3位随机数}
     */
    public static String getWriteOffCode() {
        return DateTimeUtil.getSdfTimes() + (int)((Math.random()*9+1)*10);
    }



    /**
     * 获取到退货订单号refundOrderId
     *
     * @param msgSrcId 消息来源编号  1017
     * @return 商户订单号    {来源编号(4位)}{时间(yyyyMMddmmHHssSSS)(17位)}{7位随机数}
     */
    public static String getRefundOrderId(String msgSrcId) {
        return msgSrcId + DateTimeUtil.getMsec() + (int)((Math.random()*9+1)*1000000);
    }

    // 获取HttpServletRequest里面的参数
    public static Map<String, String> getRequestParams(HttpServletRequest request) {
        Map<String, String[]> params = request.getParameterMap();
        Map<String, String> paramsRes = new HashMap<>();
        for (String key : params.keySet()) {
            String[] values = params.get(key);
            if (values.length > 0) {
                paramsRes.put(key, request.getParameter(key));
            }
        }
        log.info("银联商务通知参数：{}", paramsRes);
        log.info("银联商务签名：{}", paramsRes.get("sign"));

        return paramsRes;
    }


    public static String makeSign(String md5Key, Map<String, String> params) {
        String preStr = buildSignString(params); // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        String text = preStr + md5Key;
        System.out.println("待签名字符串："+text);
        return DigestUtils.md5Hex(getContentBytes(text)).toUpperCase();
        //return DigestUtils.sha256Hex(getContentBytes(text)).toLowerCase();
    }

    // 构建签名字符串
    public static String buildSignString(Map<String, String> params) {
        // params.put("Zm","test_test");

        if (params == null || params.size() == 0) {
            return "";
        }

        List<String> keys = new ArrayList<>(params.size());

        for (String key : params.keySet()) {
            if ("sign".equals(key))
                continue;
            if (StringUtils.isEmpty(params.get(key)))
                continue;
            keys.add(key);
        }
        //System.out.println(listToString(keys));

        Collections.sort(keys);

        StringBuilder buf = new StringBuilder();

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);

            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                buf.append(key + "=" + value);
            } else {
                buf.append(key + "=" + value + "&");
            }
        }

        return buf.toString();
    }

    // 根据编码类型获得签名内容byte[]
    public static byte[] getContentBytes(String content) {
        try {
            return content.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("签名过程中出现错误");
        }
    }


}
